00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GENVECTORMAP_HPP_
00018 #define GENVECTORMAP_HPP_
00019
00020 #include <boost/smart_ptr/shared_ptr.hpp>
00021 #include <ga.h>
00022 #include "gridpack/parallel/parallel.hpp"
00023 #include <gridpack/parallel/distributed.hpp>
00024 #include <gridpack/component/base_component.hpp>
00025 #include <gridpack/network/base_network.hpp>
00026 #include <gridpack/math/vector.hpp>
00027 #include <gridpack/utilities/exception.hpp>
00028
00029
00030
00031 namespace gridpack {
00032 namespace mapper {
00033
00034 template <class _network>
00035 class GenVectorMap {
00036 public:
00037
00038
00039
00040
00041
00042
00043 GenVectorMap(boost::shared_ptr<_network> network)
00044 : p_network(network)
00045 {
00046 p_Offsets = NULL;
00047
00048 p_timer = NULL;
00049
00050
00051 p_GAgrp = network->communicator().getGroup();
00052 p_me = GA_Pgroup_nodeid(p_GAgrp);
00053 p_nNodes = GA_Pgroup_nnodes(p_GAgrp);
00054
00055 p_Offsets = new int[p_nNodes];
00056
00057 p_nBuses = p_network->numBuses();
00058 p_nBranches = p_network->numBranches();
00059
00060 getDimensions();
00061 setOffsets();
00062 setIndices();
00063 GA_Pgroup_sync(p_GAgrp);
00064 }
00065
00066 ~GenVectorMap()
00067 {
00068 if (p_Offsets != NULL) delete [] p_Offsets;
00069 GA_Pgroup_sync(p_GAgrp);
00070 }
00071
00072
00073
00074
00075
00076 boost::shared_ptr<gridpack::math::Vector> mapToVector(void)
00077 {
00078 gridpack::parallel::Communicator comm = p_network->communicator();
00079 int blockSize = p_maxIndex-p_minIndex+1;
00080 boost::shared_ptr<gridpack::math::Vector>
00081 Ret(new gridpack::math::Vector(comm, blockSize));
00082 loadBusData(*Ret,false);
00083 loadBranchData(*Ret,false);
00084 GA_Pgroup_sync(p_GAgrp);
00085 Ret->ready();
00086 return Ret;
00087 }
00088
00089
00090
00091
00092
00093
00094 gridpack::math::Vector* intMapToVector(void)
00095 {
00096 gridpack::parallel::Communicator comm = p_network->communicator();
00097 int blockSize = p_maxIndex-p_minIndex+1;
00098 gridpack::math::Vector*
00099 Ret(new gridpack::math::Vector(comm, blockSize));
00100 loadBusData(*Ret,false);
00101 loadBranchData(*Ret,false);
00102 GA_Pgroup_sync(p_GAgrp);
00103 Ret->ready();
00104 return Ret;
00105 }
00106
00107
00108
00109
00110
00111
00112 void mapToVector(gridpack::math::Vector &vector)
00113 {
00114 int t_set, t_bus, t_branch;
00115 vector.zero();
00116 loadBusData(vector,false);
00117 loadBranchData(vector,false);
00118 GA_Pgroup_sync(p_GAgrp);
00119 vector.ready();
00120 }
00121
00122
00123
00124
00125
00126 void mapToVector(boost::shared_ptr<gridpack::math::Vector> &vector)
00127 {
00128 mapToVector(*vector);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 void mapToNetwork(const gridpack::math::Vector &vector)
00138 {
00139 int i, j, nvals;
00140 ComplexType *values = new ComplexType[p_maxValues];
00141 int *idx = new int[p_maxValues];
00142
00143 for (i=0; i<p_nBuses; i++) {
00144 if (p_network->getActiveBus(i)) {
00145 nvals = p_network->getBus(i)->vectorNumElements();
00146 p_network->getBus(i)->vectorGetElementIndices(idx);
00147 for (j=0; j<nvals; j++) {
00148 vector.getElement(idx[j],values[j]);
00149 }
00150 p_network->getBus(i)->vectorSetElementValues(values);
00151 }
00152 }
00153
00154 for (i=0; i<p_nBranches; i++) {
00155 if (p_network->getActiveBranch(i)) {
00156 nvals = p_network->getBranch(i)->vectorNumElements();
00157 p_network->getBranch(i)->vectorGetElementIndices(idx);
00158 for (j=0; j<nvals; j++) {
00159 vector.getElement(idx[j],values[j]);
00160 }
00161 p_network->getBranch(i)->vectorSetElementValues(values);
00162 }
00163 }
00164 delete [] values;
00165 delete [] idx;
00166 GA_Pgroup_sync(p_GAgrp);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 void mapToNetwork(boost::shared_ptr<gridpack::math::Vector> &vector)
00176 {
00177 mapToNetwork(*vector);
00178 }
00179
00180 private:
00181
00182
00183
00184
00185
00186 bool isLocalBranch(int idx)
00187 {
00188 int jdx1, jdx2;
00189 p_network->getBranchEndpoints(idx, &jdx1, &jdx2);
00190 bool check = true;
00191 check = check && p_network->getActiveBus(jdx1);
00192 check = check && p_network->getActiveBus(jdx2);
00193 return check;
00194 }
00195
00196
00197
00198
00199
00200 void getDimensions(void)
00201 {
00202 int i, nval;
00203
00204 int nRows = 0;
00205
00206 p_maxValues = 0;
00207 for (i=0; i<p_nBuses; i++) {
00208 if (p_network->getActiveBus(i)) {
00209 nval = p_network->getBus(i)->vectorNumElements();
00210 if (p_maxValues < nval) p_maxValues = nval;
00211 nRows += nval;
00212 }
00213 }
00214
00215 for (i=0; i<p_nBranches; i++) {
00216 if (p_network->getActiveBranch(i)) {
00217 nval = p_network->getBranch(i)->vectorNumElements();
00218 if (p_maxValues < nval) p_maxValues = nval;
00219 nRows += nval;
00220 }
00221 }
00222
00223 int *sizebuf = new int[p_nNodes];
00224 for (i=0; i<p_nNodes; i++) {
00225 sizebuf[i] = 0;
00226 }
00227 sizebuf[p_me] = nRows;
00228 char plus[2];
00229 strcpy(plus,"+");
00230 GA_Pgroup_igop(p_GAgrp, sizebuf, p_nNodes, plus);
00231
00232 p_Dim = sizebuf[0];
00233 p_Offsets[0] = 0;
00234 for (i=1; i<p_nNodes; i++) {
00235 p_Dim += sizebuf[i];
00236 p_Offsets[i] = p_Offsets[i-1] + sizebuf[i-1];
00237 }
00238 p_minIndex = p_Offsets[p_me];
00239 if (p_me < p_nNodes-1) {
00240 p_maxIndex = p_Offsets[p_me+1] - 1;
00241 } else {
00242 p_maxIndex = p_Dim - 1;
00243 }
00244 delete [] sizebuf;
00245 }
00246
00247
00248
00249
00250 void setOffsets(void)
00251 {
00252
00253 int i,j,jdx,jdx1,jdx2;
00254 int *i_bus_offsets = new int[p_nBuses];
00255 int *i_branch_offsets = new int[p_nBranches];
00256 for (i=0; i<p_nBuses; i++) {
00257 i_bus_offsets[i] = 0;
00258 }
00259 for (i=0; i<p_nBranches; i++) {
00260 i_branch_offsets[i] = 0;
00261 }
00262 int icnt = 0;
00263 int nsize;
00264
00265 for (i=0; i<p_nBuses; i++) {
00266 if (p_network->getActiveBus(i)) {
00267 i_bus_offsets[i] = icnt;
00268 icnt += p_network->getBus(i)->vectorNumElements();
00269 std::vector<int> nghbrs = p_network->getConnectedBranches(i);
00270 nsize = nghbrs.size();
00271 for (j=0; j<nsize; j++) {
00272
00273
00274
00275
00276 jdx = nghbrs[j];
00277 if (isLocalBranch(jdx)) {
00278 p_network->getBranchEndpoints(jdx,&jdx1,&jdx2);
00279 if (jdx1 == i) {
00280 i_branch_offsets[jdx] = icnt;
00281 icnt += p_network->getBranch(jdx)->vectorNumElements();
00282 }
00283 } else {
00284 if (p_network->getActiveBranch(jdx)) {
00285 i_branch_offsets[jdx] = icnt;
00286 icnt += p_network->getBranch(jdx)->vectorNumElements();
00287 }
00288 }
00289 }
00290 }
00291 }
00292
00293
00294 int **i_bus_index = new int*[p_nBuses];
00295 int **i_branch_index = new int*[p_nBranches];
00296 int *i_bus_index_buf = new int[p_nBuses];
00297 int *i_branch_index_buf = new int[p_nBranches];
00298 int *i_bus_value_buf = new int[p_nBuses];
00299 int *i_branch_value_buf = new int[p_nBranches];
00300 int i_bus_cnt = 0;
00301 int i_branch_cnt = 0;
00302 int row_offset = p_Offsets[p_me];
00303 int nbus = 0;
00304 int nbranch = 0;
00305 for (i=0; i<p_nBuses; i++) {
00306 if (p_network->getActiveBus(i)) {
00307 nbus++;
00308 i_bus_value_buf[i_bus_cnt] = i_bus_offsets[i]+row_offset;
00309 i_bus_index_buf[i_bus_cnt] = p_network->getGlobalBusIndex(i);
00310 i_bus_index[i_bus_cnt] = &i_bus_index_buf[i_bus_cnt];
00311 i_bus_cnt++;
00312 }
00313 }
00314 for (i=0; i<p_nBranches; i++) {
00315 if (p_network->getActiveBranch(i)) {
00316 nbranch++;
00317 i_branch_value_buf[i_branch_cnt] = i_branch_offsets[i]+row_offset;
00318 i_branch_index_buf[i_branch_cnt] = p_network->getGlobalBranchIndex(i);
00319 i_branch_index[i_branch_cnt] = &i_branch_index_buf[i_branch_cnt];
00320 i_branch_cnt++;
00321 }
00322 }
00323 delete [] i_bus_offsets;
00324 delete [] i_branch_offsets;
00325
00326
00327 int *t_busMap = new int[p_nNodes];
00328 int *t_branchMap = new int[p_nNodes];
00329 for (i=0; i<p_nNodes; i++) {
00330 t_busMap[i] = 0;
00331 t_branchMap[i] = 0;
00332 }
00333 t_busMap[p_me] = nbus;
00334 t_branchMap[p_me] = nbranch;
00335 char plus[2];
00336 strcpy(plus,"+");
00337 GA_Pgroup_igop(p_GAgrp, t_busMap, p_nNodes, plus);
00338 GA_Pgroup_igop(p_GAgrp, t_branchMap, p_nNodes, plus);
00339 int *busMap = new int[p_nNodes];
00340 int *branchMap = new int[p_nNodes];
00341 busMap[0] = 0;
00342 branchMap[0] = 0;
00343 int total_buses = t_busMap[0];
00344 int total_branches = t_branchMap[0];
00345 for (i=1; i<p_nNodes; i++) {
00346 busMap[i] = busMap[i-1] + t_busMap[i-1];
00347 total_buses += t_busMap[i];
00348 branchMap[i] = branchMap[i-1] + t_branchMap[i-1];
00349 total_branches += t_branchMap[i];
00350 }
00351 delete [] t_busMap;
00352 delete [] t_branchMap;
00353
00354 int one = 1;
00355 g_bus_offsets = GA_Create_handle();
00356 GA_Set_data(g_bus_offsets, one, &total_buses, C_INT);
00357 GA_Set_irreg_distr(g_bus_offsets, busMap, &p_nNodes);
00358 GA_Set_pgroup(g_bus_offsets, p_GAgrp);
00359 if (!GA_Allocate(g_bus_offsets)) {
00360 char buf[256];
00361 sprintf(buf,"GenVectorMap::setOffsets: Unable to allocate distributed array for bus offsets\n");
00362 printf("%s",buf);
00363 throw gridpack::Exception(buf);
00364 }
00365 GA_Zero(g_bus_offsets);
00366
00367 g_branch_offsets = GA_Create_handle();
00368 GA_Set_data(g_branch_offsets, one, &total_branches, C_INT);
00369 GA_Set_irreg_distr(g_branch_offsets, branchMap, &p_nNodes);
00370 GA_Set_pgroup(g_branch_offsets, p_GAgrp);
00371 if (!GA_Allocate(g_branch_offsets)) {
00372 char buf[256];
00373 sprintf(buf,"GenVectorMap::setOffsets: Unable to allocate distributed array for branch offsets\n");
00374 printf("%s",buf);
00375 throw gridpack::Exception(buf);
00376 }
00377 GA_Zero(g_branch_offsets);
00378
00379 delete [] busMap;
00380 delete [] branchMap;
00381
00382
00383 NGA_Scatter(g_bus_offsets, i_bus_value_buf, i_bus_index, i_bus_cnt);
00384 NGA_Scatter(g_branch_offsets, i_branch_value_buf, i_branch_index, i_branch_cnt);
00385 NGA_Pgroup_sync(p_GAgrp);
00386
00387 delete [] i_bus_index;
00388 delete [] i_branch_index;
00389
00390 delete [] i_bus_index_buf;
00391 delete [] i_branch_index_buf;
00392 delete [] i_bus_value_buf;
00393 delete [] i_branch_value_buf;
00394 }
00395
00396
00397
00398
00399
00400
00401 void setIndices(void)
00402 {
00403
00404 int **bus_index = new int*[p_nBuses];
00405 int **branch_index = new int*[p_nBranches];
00406 int *bus_index_buf = new int[p_nBuses];
00407 int *branch_index_buf = new int[p_nBranches];
00408 int *i_bus_value_buf = new int[p_nBuses];
00409 int *i_branch_value_buf = new int[p_nBranches];
00410 int i, j;
00411
00412 for (i=0; i<p_nBuses; i++) {
00413 bus_index_buf[i] = p_network->getGlobalBusIndex(i);
00414 bus_index[i] = &bus_index_buf[i];
00415 }
00416 for (i=0; i<p_nBranches; i++) {
00417 branch_index_buf[i] = p_network->getGlobalBranchIndex(i);
00418 branch_index[i] = &branch_index_buf[i];
00419 }
00420 NGA_Gather(g_bus_offsets, i_bus_value_buf, bus_index, p_nBuses);
00421 NGA_Gather(g_branch_offsets, i_branch_value_buf, branch_index, p_nBranches);
00422
00423
00424 int offset, nrows, ncols, idx;
00425 for (i=0; i<p_nBuses; i++) {
00426 nrows = p_network->getBus(i)->vectorNumElements();
00427 if (nrows > 0) {
00428 offset = i_bus_value_buf[i];
00429 for (j=0; j<nrows; j++) {
00430 idx = offset+j;
00431 p_network->getBus(i)->vectorSetElementIndex(j,idx);
00432 }
00433 }
00434 }
00435 for (i=0; i<p_nBranches; i++) {
00436 nrows = p_network->getBranch(i)->vectorNumElements();
00437 if (nrows > 0) {
00438 offset = i_branch_value_buf[i];
00439 for (j=0; j<nrows; j++) {
00440 idx = offset+j;
00441 p_network->getBranch(i)->vectorSetElementIndex(j,idx);
00442 }
00443 }
00444 }
00445
00446 delete [] bus_index;
00447 delete [] branch_index;
00448
00449 delete [] bus_index_buf;
00450 delete [] branch_index_buf;
00451 delete [] i_bus_value_buf;
00452 delete [] i_branch_value_buf;
00453
00454
00455 GA_Destroy(g_bus_offsets);
00456 GA_Destroy(g_branch_offsets);
00457 }
00458
00459
00460
00461
00462
00463
00464 void loadBusData(gridpack::math::Vector &vector, bool flag)
00465 {
00466 int i, j, nvals;
00467 ComplexType *values = new ComplexType[p_maxValues];
00468 int *idx = new int[p_maxValues];
00469 for (i=0; i<p_nBuses; i++) {
00470 if (p_network->getActiveBus(i)) {
00471 nvals = p_network->getBus(i)->vectorNumElements();
00472 p_network->getBus(i)->vectorGetElementValues(values, idx);
00473 for (j=0; j<nvals; j++) {
00474 if (flag) {
00475 vector.addElement(idx[j],values[j]);
00476 } else {
00477 vector.setElement(idx[j],values[j]);
00478 }
00479 }
00480 }
00481 }
00482 delete [] values;
00483 delete [] idx;
00484 }
00485
00486
00487
00488
00489
00490
00491 void loadBranchData(gridpack::math::Vector &vector, bool flag)
00492 {
00493 int i, j, nvals;
00494 ComplexType *values = new ComplexType[p_maxValues];
00495 int *idx = new int[p_maxValues];
00496 for (i=0; i<p_nBranches; i++) {
00497 if (p_network->getActiveBranch(i)) {
00498 nvals = p_network->getBranch(i)->vectorNumElements();
00499 p_network->getBranch(i)->vectorGetElementValues(values,idx);
00500 for (j=0; j<nvals; j++) {
00501 if (idx[j] >= p_minIndex && idx[j] <= p_maxIndex) {
00502 if (flag) {
00503 vector.addElement(idx[j],values[j]);
00504 } else {
00505 vector.setElement(idx[j],values[j]);
00506 }
00507 }
00508 }
00509 }
00510 }
00511 delete [] values;
00512 delete [] idx;
00513 }
00514
00515
00516 int p_me;
00517 int p_nNodes;
00518
00519
00520 boost::shared_ptr<_network> p_network;
00521 int p_nBuses;
00522 int p_nBranches;
00523
00524
00525 int p_Dim;
00526 int p_minIndex;
00527 int p_maxIndex;
00528 int p_maxValues;
00529 #ifdef NZ_PER_ROW
00530 int* p_nz_per_row;
00531 #endif
00532
00533 int* p_Offsets;
00534
00535
00536 int g_bus_offsets;
00537 int g_branch_offsets;
00538 int p_GAgrp;
00539
00540
00541 gridpack::utility::CoarseTimer *p_timer;
00542
00543 };
00544
00545 }
00546 }
00547
00548 #endif //GENVECTORMAP_HPP_